// ======= 全局消息提示框 - 使用新的消息系统 =======
function showMessage(message, duration = 2000) {
    if (window.messageUtils && typeof window.messageUtils.info === 'function') {
        window.messageUtils.info(message, duration);
    } else {
        // 降级处理：如果消息系统未加载，使用 console + alert
        console.warn('消息系统未加载，使用 alert 降级处理：', message);
        try { alert(message); } catch (e) { console.log(message); }
    }
}

// ======= 通用请求封装 =======
async function apiRequest(url, options = {}) {
    const token = localStorage.getItem("token");

    const headers = {
        "Content-Type": "application/json",
        ...(options.headers || {}),
        ...(token ? { Authorization: token } : {}),
    };

    // 如果URL不是完整的HTTP路径，使用API配置或默认前缀
    if (!url.startsWith('http://') && !url.startsWith('https://')) {
        if (typeof getApiUrl === 'function') {
            url = getApiUrl(url);
        } else {
            url = 'http://localhost:8080' + url;
        }
    }

    const response = await fetch(url, { ...options, headers });

    if (response.status === 401) {
        if (window.messageUtils && typeof window.messageUtils.error === 'function') {
            window.messageUtils.error("登录已过期，请重新登录！");
        } else {
            showMessage("登录已过期，请重新登录！");
        }
        localStorage.removeItem("token");
        localStorage.removeItem("isAdmin");
        window.location.href = "/index.html";
        throw new Error("未授权或 token 过期");
    }

    // 期望后端返回标准结构 { code, message, data }
    const json = await response.json();
    return json;
}

// ======= 页面主逻辑（安全、鲁棒性增强版） =======
document.addEventListener("DOMContentLoaded", async () => {
    // 尝试获取 UI 元素；不存在则尝试创建一个 main-content 容器，避免空引用错误
    const usernameSpan = document.getElementById("username");
    const userAvatar = document.getElementById("user-avatar");
    const logoutBtn = document.querySelector(".logout-btn");

    let content = document.getElementById("main-content");
    if (!content) {
        // create fallback main-content to avoid runtime errors
        content = document.createElement("div");
        content.id = "main-content";
        // 插到 body 末尾；如果页面布局依赖位置你可以手动移动
        document.body.appendChild(content);
        console.warn("未找到 #main-content，已自动创建一个占位元素（id=main-content）。");
    }

    // 1️⃣ 加载用户信息（非阻塞）
    (async function loadUserInfo() {
        if (!usernameSpan && !userAvatar) return;
        try {
            const res = await apiRequest("/api/user/info");
            if (res && res.code === 200 && res.data) {
                const user = res.data;
                if (usernameSpan) usernameSpan.textContent = user.username || "未知用户";
                if (userAvatar) userAvatar.src = user.avatar || "/images/default-avatar.png";
            } else {
                console.warn("获取用户信息失败：", res && res.message);
                if (usernameSpan) usernameSpan.textContent = "游客";
            }
        } catch (e) {
            console.warn("加载用户信息异常：", e);
            if (usernameSpan) usernameSpan.textContent = "游客";
        }
    })();

    // 2️⃣ 注销逻辑（防重复）
    if (logoutBtn) {
        logoutBtn.addEventListener("click", async () => {
            try {
                await apiRequest("/api/logout", { method: "POST" });
            } catch (e) {
                // 即便请求失败，也清理本地并跳回登录页
                console.warn("logout request failed:", e);
            } finally {
                localStorage.removeItem("token");
                localStorage.removeItem("isAdmin");
                window.location.href = "/index.html";
            }
        });
    }

    // ========== 侧栏（radio）交互修复与增强 ==========
    const radioContainer = document.querySelector('.radio-container');
    const radios = document.querySelectorAll('.radio-container input[name="radio"]');

    // 保证有至少一个 radio
    if (!radioContainer || radios.length === 0) {
        console.warn("侧栏 radio 未找到（.radio-container 或 input[name='radio']），侧栏切换功能将无法使用。");
    }

    // 并发控制：当多个切换请求并发触发时，保留最后一次请求执行
    let sectionQueueToken = 0;
    let isSectionLoading = false;

    async function queuedLoadSection(section) {
        const myToken = ++sectionQueueToken;
        // small debounce: if many calls come quickly, schedule last one
        // mark loading state and allow later calls to supersede earlier ones
        isSectionLoading = true;
        try {
            await loadSection(section, myToken);
        } finally {
            // if this token is latest -> clear loading flag
            if (myToken === sectionQueueToken) {
                isSectionLoading = false;
            }
        }
    }

    // 绑定 input change（当选项变化时触发）
    radios.forEach(radio => {
        radio.addEventListener("change", (e) => {
            if (e.target.checked) {
                const value = e.target.id.replace("radio-", "");
                queuedLoadSection(value);
            }
        });
    });

    // 同时绑定 label 点击（确保即使点已选中项，也会触发加载）
    if (radioContainer) {
        radioContainer.addEventListener("click", (e) => {
            const label = e.target.closest("label");
            if (!label) return;
            const forId = label.getAttribute("for");
            if (!forId) return;
            const input = document.getElementById(forId);
            if (!input) return;
            // 如果 input 不处于 checked，设置为 checked 会触发 change 自动调用 queuedLoadSection
            if (!input.checked) {
                input.checked = true;
                // change event will fire and handle queuedLoadSection
                input.dispatchEvent(new Event('change', { bubbles: true }));
            } else {
                // 如果已经是 checked（点击已选项），我们手动触发一次加载以保证刷新
                const value = input.id.replace("radio-", "");
                queuedLoadSection(value);
            }
        });
    }

    // 默认加载 first checked radio 或 "recommend"
    (function initialLoad() {
        const checked = document.querySelector('.radio-container input[name="radio"]:checked');
        const initialSection = checked ? checked.id.replace("radio-", "") : "recommend";
        queuedLoadSection(initialSection);
    })();

    // ======= loadSection 主入口（接收 token，便于并发处理） =======
    async function loadSection(section, token = null) {
        // token 用于并发控制：只在必要时保证最后执行
        // 显示加载占位
        try {
            content.innerHTML = `<p style="color:#555;">加载中...</p>`;
            switch (section) {
                case "recommend": await safeCall(loadRecommend); break;
                case "history": await safeCall(loadHistory); break;
                case "current": await safeCall(loadCurrentBorrow); break;
                case "borrow": await safeCall(loadBookSearch); break;
                case "personal": await safeCall(loadPersonalCenter); break;
                case "collection": await safeCall(loadCollection); break;
                default:
                    content.innerHTML = `<p>未知模块：${section}</p>`;
            }
        } catch (err) {
            console.error("loadSection 异常：", err);
            showMessage("页面加载失败，请稍后重试");
            // 若报错，保留先前内容不会卡在空白太久——可恢复为更友好的界面
            content.innerHTML = `<p style="color:red;">加载失败，请稍后重试。</p>`;
        }
    }

    // helper: 在模块函数调用时统一捕获错误，防止阻塞后续交互
    async function safeCall(fn) {
        try {
            await fn();
        } catch (err) {
            console.error("模块加载出错：", err);
            showMessage("模块加载失败：" + (err && err.message ? err.message : ""));
            // 保证 content 有个错误提示
            content.innerHTML = `<p style="color:red;">模块加载失败，请稍后再试。</p>`;
        }
    }

    // ================= 各模块实现（保持你的原实现，增强错误保护） =================

    // ======= 新书推荐 =======
    async function loadRecommend() {
        const res = await apiRequest("/api/books/latest");
        if (res.code !== 200) throw new Error(res.message || "加载失败");
        const books = res.data || [];
        content.innerHTML = "";
        if (!books.length) {
            content.innerHTML = "<p style='text-align:center;color:#777;'>暂无新书推荐</p>";
            return;
        }
        const wrapper = document.createElement("div");
        wrapper.className = "card-grid";
        books.forEach(book => {
            const card = document.createElement("div");
            card.className = "card";
            card.innerHTML = `
                <div class="book-cover-wrapper">
                    <img src="${book.coverUrl || '/images/default-cover.png'}" alt="${book.title}" class="book-cover" />
                </div>
                <div class="book-info">
                    <h3 class="book-title">${escapeHtml(book.title)}</h3>
                    <p class="book-author">${escapeHtml(book.author || '')}</p>
                </div>
            `;
            card.addEventListener("click", () => {
                // 跳转到详情页（保持你原来的约定）
                window.location.href = `/book/${book.id}`;
            });
            wrapper.appendChild(card);
        });
        content.appendChild(wrapper);
    }

    // ======= 借阅历史 =======
    async function loadHistory() {
        const res = await apiRequest("/api/user/history");
        if (res.code !== 200) throw new Error(res.message || "加载失败");
        const history = res.data || [];

        content.innerHTML = "<h2>借阅历史</h2>";
        if (!history.length) {
            content.innerHTML += `<p style="color:#888;">暂无借阅记录</p>`;
            return;
        }

        const list = document.createElement("div");
        list.className = "history-list";

        history.forEach(record => {
            const card = document.createElement("div");
            card.className = "history-card";
            const statusColor = record.status === "已逾期" ? "#ff4d4f" : "#4caf50";
            card.innerHTML = `
                ${record.status === "已逾期" ? `<div class="tag-overdue">已逾期</div>` : ""}
                <div class="history-info">
                    <div class="book-title">${escapeHtml(record.bookTitle)}</div>
                    <div class="book-status" style="color:${statusColor};">${escapeHtml(record.status)}</div>
                </div>
                <div class="book-dates">
                    <p>借阅时间：${escapeHtml(record.borrowDate || "-")}</p>
                    <p>归还时间：${escapeHtml(record.returnDate || "未归还")}</p>
                </div>
                <button class="delete-btn" data-id="${record.id}">删除</button>
            `;
            list.appendChild(card);
        });

        content.appendChild(list);

        // 事件代理绑定删除（比每个绑定更稳健）
        list.addEventListener("click", async (e) => {
            const btn = e.target.closest(".delete-btn");
            if (!btn) return;
            const id = btn.dataset.id;
            if (!confirm("确定要删除这条借阅记录吗？")) return;

            try {
                const delRes = await apiRequest(`/api/user/history/${id}`, { method: "DELETE" });
                if (delRes.code === 200) {
                    btn.closest(".history-card").remove();
                    showMessage("删除成功");
                } else {
                    showMessage("删除失败：" + (delRes.message || ""));
                }
            } catch (err) {
                console.error("删除异常：", err);
                showMessage("删除失败，请稍后重试");
            }
        });
    }

    // ======= 当前借阅 =======
    async function loadCurrentBorrow() {
        const res = await apiRequest("/api/user/current");
        if (res.code !== 200) throw new Error(res.message || "加载失败");
        const listData = res.data || [];

        content.innerHTML = "<h2>当前借阅</h2>";
        const container = document.createElement("div");
        container.className = "history-list";
        if (!listData.length) {
            container.innerHTML = `<p style="color:#777;">暂无当前借阅记录</p>`;
            content.appendChild(container);
            return;
        }

        listData.forEach(item => {
            const card = document.createElement("div");
            card.className = "history-card";

            const dueDate = item.dueDate ? new Date(item.dueDate) : null;
            const now = new Date();
            const isNearDue = dueDate ? ((dueDate - now) / (1000 * 60 * 60 * 24) <= 3) : false;
            const isOverdue = dueDate ? (dueDate < now) : false;

            const statusText = isOverdue ? "已逾期" : (isNearDue ? "即将到期" : "正常");
            const statusColor = isOverdue ? "#ff4d4f" : (isNearDue ? "#ff9800" : "#4caf50");

            card.innerHTML = `
                ${isOverdue ? `<div class="tag-overdue">已逾期</div>` : ""}
                <div class="history-info">
                    <div class="book-title">${escapeHtml(item.bookTitle)}</div>
                    <div class="book-status" style="color:${statusColor};">${escapeHtml(statusText)}</div>
                </div>
                <div class="book-dates">
                    <p>借阅日期：${escapeHtml(item.borrowDate || "-")}</p>
                    <p>到期时间：${escapeHtml(item.dueDate || "-")}</p>
                </div>
                <button class="return-btn" data-id="${item.id}">归还</button>
            `;
            container.appendChild(card);
        });

        content.appendChild(container);

        // 事件代理处理归还
        container.addEventListener("click", async (e) => {
            const btn = e.target.closest(".return-btn");
            if (!btn) return;
            const id = btn.dataset.id;
            if (!confirm("确认归还这本书吗？")) return;
            try {
                const r = await apiRequest(`/api/books/return/${id}`, { method: "POST" });
                if (r.code === 200) {
                    btn.closest(".history-card").remove();
                    showMessage("归还成功");
                } else {
                    showMessage("归还失败：" + (r.message || ""));
                }
            } catch (err) {
                console.error("归还异常：", err);
                showMessage("归还失败，请稍后再试");
            }
        });
    }

    // ======= 图书搜索（分页） =======
    async function loadBookSearch() {
        content.innerHTML = `
          <link rel="stylesheet" href="/css/userHomePage.css">
          <h2 style="text-align:center;">图书借阅</h2>
          <div class="search-container">
            <div class="custom-dropdown" id="book-type-dropdown">
              <div class="dropdown-selected"><span id="dropdown-label">加载中...</span><span class="dropdown-arrow">▾</span></div>
              <div class="dropdown-list" id="dropdown-list"></div>
            </div>
            <div class="search-box">
              <input type="text" class="search-input" id="book-search" placeholder="输入书名关键字..." />
              <button class="search-btn" id="search-btn">🔍</button>
            </div>
          </div>
          <div id="search-result" class="book-list"></div>
          <div id="pagination" class="pagination"></div>
        `;

        const dropdown = document.getElementById("book-type-dropdown");
        const selected = dropdown.querySelector(".dropdown-selected");
        const list = document.getElementById("dropdown-list");
        const label = document.getElementById("dropdown-label");

        let selectedType = "全部类型";
        let keyword = "";
        let currentPage = 1;
        const pageSize = 8;

        async function loadCategories() {
            list.innerHTML = `<div class="dropdown-option">全部类型</div>`;
            label.textContent = "全部类型";
            try {
                const res = await apiRequest("/api/book/categories");
                if (res.code !== 200) throw new Error(res.message || "加载失败");
                const categories = res.data || [];
                list.innerHTML = `<div class="dropdown-option">全部类型</div>`;
                categories.forEach(cat => {
                    const div = document.createElement("div");
                    div.className = "dropdown-option";
                    div.textContent = cat;
                    list.appendChild(div);
                });
            } catch (err) {
                console.warn("加载分类失败：", err);
                list.innerHTML = `<div class="dropdown-option disabled">加载失败</div>`;
            }
        }

        await loadCategories();

        selected.addEventListener("click", () => dropdown.classList.toggle("open"));
        list.addEventListener("click", e => {
            const option = e.target.closest(".dropdown-option");
            if (!option || option.classList.contains("disabled")) return;
            label.textContent = option.textContent;
            selectedType = option.textContent;
            dropdown.classList.remove("open");
            currentPage = 1;
            loadBooks();
        });
        document.addEventListener("click", e => {
            if (!dropdown.contains(e.target)) dropdown.classList.remove("open");
        });

        async function loadBooks() {
            const resultDiv = document.getElementById("search-result");
            const paginationDiv = document.getElementById("pagination");
            resultDiv.innerHTML = "<p style='text-align:center;'>加载中...</p>";
            paginationDiv.innerHTML = "";

            try {
                const params = new URLSearchParams({
                    page: currentPage,
                    size: pageSize,
                    keyword,
                    type: selectedType
                });

                const res = await apiRequest(`/api/books/page?${params.toString()}`);
                if (res.code !== 200) throw new Error(res.message || "加载失败");

                const data = res.data || {};
                const books = data.records || [];
                const total = data.total || 0;

                resultDiv.innerHTML = "";

                if (!books.length) {
                    resultDiv.innerHTML = "<p style='text-align:center;'>暂无书籍。</p>";
                    return;
                }

                const wrapper = document.createElement("div");
                wrapper.className = "book-grid";
                books.forEach(b => {
                    const card = document.createElement("div");
                    card.className = "book-card";
                    card.innerHTML = `
                        <div class="book-cover"><img src="${b.coverUrl || '/images/img.png'}" alt="${escapeHtml(b.title)}"></div>
                        <div class="book-info">
                          <h3 class="book-title">${escapeHtml(b.title)}</h3>
                          <p class="book-author">${escapeHtml(b.author)}</p>
                        </div>
                    `;
                    card.addEventListener("click", () => {
                        window.location.href = `/book/${b.id}`;
                    });
                    wrapper.appendChild(card);
                });
                resultDiv.appendChild(wrapper);

                // 分页
                const totalPages = Math.max(1, Math.ceil(total / pageSize));
                if (totalPages > 1) {
                    const pagination = document.createElement("div");
                    pagination.className = "pagination-buttons";

                    const prevBtn = document.createElement("button");
                    prevBtn.textContent = "上一页";
                    prevBtn.disabled = currentPage === 1;
                    prevBtn.addEventListener("click", () => {
                        if (currentPage > 1) { currentPage--; loadBooks(); }
                    });

                    const nextBtn = document.createElement("button");
                    nextBtn.textContent = "下一页";
                    nextBtn.disabled = currentPage === totalPages;
                    nextBtn.addEventListener("click", () => {
                        if (currentPage < totalPages) { currentPage++; loadBooks(); }
                    });

                    const info = document.createElement("span");
                    info.textContent = `第 ${currentPage} / ${totalPages} 页`;

                    pagination.append(prevBtn, info, nextBtn);
                    paginationDiv.appendChild(pagination);
                }

            } catch (err) {
                console.error("加载书籍失败：", err);
                resultDiv.innerHTML = "<p style='text-align:center;'>加载失败，请稍后再试。</p>";
            }
        }

        document.getElementById("search-btn").addEventListener("click", () => {
            keyword = document.getElementById("book-search").value.trim();
            currentPage = 1;
            loadBooks();
        });

        await loadBooks();
    }

    // ======= 个人中心（编辑资料 + 头像预览 + 修改密码） =======
    async function loadPersonalCenter() {
        content.innerHTML = `
  <div class="personal-center">
    <div class="personal-inner">
      <div class="edit-profile-container">
        <div class="edit-card">
          <div class="avatar-section">
            <img id="user-avatar" src="/images/default-avatar.png" alt="用户头像" title="点击更换头像" style="cursor:pointer;border-radius:50%;width:96px;height:96px;object-fit:cover;">
            <input type="file" id="avatar-upload" accept="image/*" style="display:none;">
          </div>
          <h2>编辑个人资料</h2>
          <form id="edit-form">
            <div class="form-group">
              <label for="nickname">昵称：</label>
              <input type="text" id="nickname" name="nickname" placeholder="请输入昵称" required>
            </div>
            <div class="form-group">
              <label for="email">邮箱：</label>
              <input type="email" id="email" name="email" placeholder="请输入邮箱" required>
            </div>
            <div class="btn-group">
              <button type="submit" class="save-btn">保存修改</button>
              <button type="button" id="change-password-btn" class="pwd-btn">修改密码</button>
            </div>
          </form>
        </div>
        <div class="modal" id="password-modal" style="display:none;">
          <div class="modal-content">
            <h3>修改密码</h3>
            <input type="password" id="old-password" placeholder="原密码" required>
            <input type="password" id="new-password" placeholder="新密码" required>
            <input type="password" id="confirm-password" placeholder="确认新密码" required>
            <div class="modal-btns">
              <button id="confirm-change">确认修改</button>
              <button id="cancel-change">取消</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
`;

        // 获取并显示用户信息（容错）
        try {
            const res = await apiRequest("/api/user/info");
            if (res && res.code === 200) {
                const user = res.data || {};
                document.getElementById("nickname").value = user.nickname || "";
                document.getElementById("email").value = user.email || "";
                const avatarEl = document.getElementById("user-avatar");
                avatarEl.src = user.avatar || "/images/default-avatar.png";
            } else {
                showMessage("加载用户信息失败：" + (res && res.message ? res.message : ""));
            }
        } catch (err) {
            console.warn("加载用户信息异常：", err);
            showMessage("加载用户信息失败，请稍后再试");
        }

        // 头像上传预览（本地预览）
        const avatarImg = document.getElementById("user-avatar");
        const avatarUpload = document.getElementById("avatar-upload");
        avatarImg.addEventListener("click", () => avatarUpload.click());
        avatarUpload.addEventListener("change", () => {
            const file = avatarUpload.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = e => avatarImg.src = e.target.result;
                reader.readAsDataURL(file);
            }
        });

        // 保存资料（提交到后端）
        document.getElementById("edit-form").addEventListener("submit", async (e) => {
            e.preventDefault();
            const nickname = document.getElementById("nickname").value.trim();
            const email = document.getElementById("email").value.trim();
            if (!nickname || !email) { showMessage("请填写完整信息"); return; }

            try {
                const res = await apiRequest("/api/user/update", {
                    method: "POST",
                    body: JSON.stringify({ nickname, email })
                });
                if (res.code === 200) {
                    showMessage("资料修改成功");
                } else {
                    showMessage("保存失败：" + (res.message || ""));
                }
            } catch (err) {
                console.error("保存失败：", err);
                showMessage("保存失败，请稍后再试");
            }
        });

        // 修改密码弹窗逻辑
        const modal = document.getElementById("password-modal");
        document.getElementById("change-password-btn").addEventListener("click", () => { modal.style.display = "flex"; });
        document.getElementById("cancel-change").addEventListener("click", () => { modal.style.display = "none"; });

        document.getElementById("confirm-change").addEventListener("click", async () => {
            const oldPwd = document.getElementById("old-password").value.trim();
            const newPwd = document.getElementById("new-password").value.trim();
            const confirmPwd = document.getElementById("confirm-password").value.trim();
            if (!oldPwd || !newPwd || !confirmPwd) { showMessage("请填写完整信息"); return; }
            if (newPwd !== confirmPwd) { showMessage("两次输入的新密码不一致"); return; }

            try {
                const res = await apiRequest("/api/user/changePassword", {
                    method: "POST",
                    body: JSON.stringify({ oldPassword: oldPwd, newPassword: newPwd })
                });
                if (res.code === 200) {
                    showMessage("密码修改成功");
                    modal.style.display = "none";
                    document.getElementById("old-password").value = "";
                    document.getElementById("new-password").value = "";
                    document.getElementById("confirm-password").value = "";
                } else {
                    showMessage("修改失败：" + (res.message || ""));
                }
            } catch (err) {
                console.error("修改密码异常：", err);
                showMessage("修改密码失败，请稍后再试");
            }
        });
    }

    // ======= 我的收藏 =======
    // ========== 我的收藏 ==========
    async function loadCollection() {
        content.innerHTML = "<h2>我的收藏</h2><p>加载中...</p>";

        try {
            const res = await apiRequest("/api/user/collection");
            if (res.code !== 200) throw new Error(res.message || "加载失败");

            const books = res.data || [];

            content.innerHTML = "<h2>我的收藏</h2>";

            const container = document.createElement("div");
            container.className = "history-list"; // 复用你已有的列表布局
            content.appendChild(container);

            if (!books.length) {
                container.innerHTML = `<p style="color:#777;">暂无收藏</p>`;
                return;
            }

            books.forEach(b => {
                const card = document.createElement("div");
                card.className = "history-card";

                card.innerHTML = `
                <div class="history-info">
                    <div class="book-title">《${escapeHtml(b.title)}》</div>
                    <div class="book-status">${escapeHtml(b.author || "未知作者")}</div>
                </div>

                <div class="book-dates">
                    <p>收藏时间：${b.collectTime || "-"}</p>
                </div>

                <button class="delete-btn" data-id="${b.id}">取消收藏</button>
            `;

                container.appendChild(card);
            });

            // ======= 绑定取消收藏事件 =======
            document.querySelectorAll(".delete-btn").forEach(btn => {
                btn.addEventListener("click", async () => {
                    const id = btn.dataset.id;

                    if (!confirm("确定取消收藏该书籍吗？")) return;

                    try {
                        const res = await apiRequest("/api/user/uncollect", {
                            method: "POST",
                            body: JSON.stringify({ id })
                        });

                        if (res.code !== 200) throw new Error(res.message);

                        alert("已取消收藏");
                        loadCollection(); // 重新加载
                    } catch (err) {
                        alert("取消失败：" + err.message);
                    }
                });
            });

        } catch (err) {
            content.innerHTML = `<h2>我的收藏</h2><p style="color:red;">加载失败：${err.message}</p>`;
        }
    }

    // ================= helper utils =================
    function escapeHtml(str = "") {
        return String(str)
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }
});
